// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// S [author] rhyme_lph
// m [email]  rhymelph@gmail.com
// e [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/bill_entity.dart';
import 'package:finance_app/src/entities/invoice_entity.dart';
import 'package:finance_app/src/entities/payment_detail_entity.dart';
import 'package:finance_app/src/http_service/http_bill_service.dart';
import 'package:finance_app/src/http_service/http_credit_note_service.dart';
import 'package:finance_app/src/http_service/http_debit_note_service.dart';
import 'package:finance_app/src/http_service/http_expense_service.dart';
import 'package:finance_app/src/http_service/http_invoice_service.dart';
import 'package:finance_app/src/http_service/http_payment_service.dart';
import 'package:finance_app/src/mixin/refresh_mixin.dart';
import 'package:finance_app/src/provider/dashboard/bill/new_bill_provider.dart';
import 'package:finance_app/src/provider/dashboard/dashboard_view_provider.dart';
import 'package:finance_app/src/provider/dashboard/expense/new_expense_provider.dart';
import 'package:finance_app/src/provider/dashboard/invoice/new_invoice_provider.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:dio/dio.dart';
import 'package:finance_app/src/utils/permission_utils.dart';

class SeePaymentProvider extends BaseProvider<List<PaymentDetailEntity>>
    with RefreshMixin<List<PaymentDetailEntity>, List<PaymentDetailEntity>> {
  List<String> menuList = [
    'Delete',
    'Make Payment',
  ];

  bool isDeleteModel = false;

  //cash out
  int billId;
  String billNumber;

  int expenseId;

  int creditId;

  int debitId;

  bool isClosed;

  bool get isCashOut =>
      (billId != null && billNumber != null) || creditId != null;

  // cash in
  int invoiceId;
  String invoiceNumber;

  bool get isCashIn =>
      (invoiceId != null && invoiceNumber != null) || debitId != null;

  List<PaymentDetailEntity> currentSelect = [];

  @override
  void initState() {
    super.initState();
  }

  @override
  Future get dataFuture {
    if (expenseId != null) {
      return HttpExpenseService.getPaymentList(expenseId);
    } else if (debitId != null) {
      return HttpDebitNoteService.debitPayment(debitId);
    } else if (creditId != null) {
      return HttpCreditNoteService.creditPayment(creditId);
    }
    return isCashOut
        ? HttpBillService.billPayment(billId)
        : HttpInvoiceService.invoicePayment(invoiceId);
  }

  @override
  Future get refreshFuture => dataFuture;

  void onSelectMenu(String value) {
    switch (value) {
      case 'Delete':
        onChangeDeleteMode();
        break;
      case 'Make Payment':
        onAdd();
        break;
    }
  }

  void onCancel() {
    onChangeDeleteMode();
    currentSelect.clear();
    update();
  }

  void onDelete() async {
    if (currentSelect.length == 0) {
      showToast(S.current.please_select_payment_to_delete);
      return;
    }
    List<int> ids = currentSelect.map((e) => e.id).toList();

    bool isSuccess = false;
    await post(HttpPaymentService.deletePayments(ids),
        loadingTip: S.current.loading,
        autoHandler: AutoHandler.Toast, onSuccess: (result) {
      isSuccess = true;
    });
    if (isSuccess) {
      onChangeDeleteMode();
      data.removeWhere((element) => currentSelect.contains(element));
      currentSelect.clear();
      update();
      if (isCashOut) {
        Providers.get<NewBillProvider>(RouterGenProviders.newBillPage, null)
            ?.onTry();
      }
      if (isCashIn) {
        Providers.get<NewInvoiceProvider>(
                RouterGenProviders.newInvoicePage, null)
            ?.onTry();
      }
      if (expenseId != null) {
        Providers.get<NewExpenseProvider>(
                RouterGenProviders.newExpensePage, null)
            ?.onTry();
      }
      if (Config.hasPermission(PermissionUtils.homeDashboard)) {
        Config.dashboardProvider
            ?.getChildProvider<DashboardViewProvider>()
            ?.loadData();
      }
    }
  }

  void onAdd() async {
    var result;
    if (isCashOut) {
      final bill =
          Providers.get<NewBillProvider>(RouterGenProviders.newBillPage, null);
      BillEntity b = BillEntity()
        ..id = billId
        ..number = billNumber;
      result =
          await Routes.navigateTo(RouterGenProviders.newCashOutPage, params: {
        'billList': [b],
        'total': bill.totalDiscount,
        'currency': bill.currency,
        'paidTo': bill.supplier,
        'isSelectMode': true,
      });
      bill.onTry();
    }
    if (isCashIn) {
      final invoice = Providers.get<NewInvoiceProvider>(
          RouterGenProviders.newInvoicePage, null);

      List<InvoiceEntity> invoiceList = [
        InvoiceEntity()
          ..id = invoiceId
          ..number = invoiceNumber
      ];
      result = await Routes.navigateTo(
        RouterGenProviders.newCashInPage,
        params: {
          'invoiceList': invoiceList,
          'receiveFrom': invoice.client,
          'total': invoice.totalDiscount,
          'currency': invoice.currency,
          'isSelectMode': true,
        },
      );
      invoice.onTry();
    }
    if (expenseId != null) {
      final expense = Providers.get<NewExpenseProvider>(
          RouterGenProviders.newExpensePage, null);
      result = await Routes.navigateTo(
        RouterGenProviders.newCashOutPage,
        params: {
          'total': expense.total,
          'type': 'expense',
          'isSelectMode': true,
        },
      );
      expense.onTry();
    }
    if (result != null) {
      refreshController.requestRefresh();
    }
  }

  void onChangeDeleteMode() {
    isDeleteModel = !isDeleteModel;
    update();
  }

  void onAddPayment(PaymentDetailEntity item1) {
    if (currentSelect.contains(item1)) {
      currentSelect.remove(item1);
    } else {
      currentSelect.add(item1);
    }
    update();
  }

  @override
  List<PaymentDetailEntity> get dataList => data;

  @override
  List<PaymentDetailEntity> getFromRequestResult(
      Response<dynamic> result, bool isRefresh) {
    return getEntityFromResult<List<PaymentDetailEntity>>(result);
  }

  void onNavDetail(PaymentDetailEntity item1) async {
    print("here");
    var result;
    if (isCashOut) {
      result =
          await Routes.navigateTo(RouterGenProviders.newCashOutPage, params: {
        'detailData': item1,
        'isSelectMode': true,
      });
    }
    if (isCashIn) {
      result = await Routes.navigateTo(
        RouterGenProviders.newCashInPage,
        params: {
          'detailData': item1,
          'isSelectMode': true,
        },
      );
    }
    if (expenseId != null) {
      result = await Routes.navigateTo(
        RouterGenProviders.newCashOutPage,
        params: {
          'detailData': item1,
          'type': 'expense',
          'isSelectMode': true,
        },
      );
    }
    if (result != null) {
      refreshController.requestRefresh();
    }
  }

  @override
  FutureOr<List<PaymentDetailEntity>> transformData(
      List<PaymentDetailEntity> d, bool isCache) {
    if (d.last.status == "closed") {
      menuList.remove("Make Payment");
    }
    return d;
  }
}
